package com.wanwu.channel.common.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class IdUtil {

    private static final Logger log = LoggerFactory.getLogger(IdUtil.class);

    private static long lastTimestamp = -1L;

    private static final int sequenceMask = 9;

    private static int sequence = 0;

    private static final Random r = new Random();

    private static char[] A2Z = null;

    static {
        int j = 0;
        A2Z = new char[26];
        for (int i = 65; i < 91; i++) {
            A2Z[j] = (char) i;
            j++;
        }
    }

    public synchronized static String nextyyyyMMddId() {
        long timestamp = timeGen();
        if (timestamp < lastTimestamp) {
            throw new RuntimeException(String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
        }
        if (lastTimestamp == timestamp) {
            if (sequence == sequenceMask) {
                sequence = 0;
                timestamp = tilNextMillis(lastTimestamp);
            } else {
                sequence = sequence + 1;
            }
        } else {
            sequence = 0;
        }

        lastTimestamp = timestamp;
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(timestamp);
        Date date1 = c.getTime();
        return new SimpleDateFormat("yyyyMMdd").format(date1) + String.format("%01d", sequence);
    }

    public static String get12OrderId() {
        try {
            String id = nextyyyyMMddId();
            return id + String.format("%02d", r.nextInt(9999));
        } catch (Exception e) {
            log.error("get12OrderId Exception:", e);
        }

        return new SimpleDateFormat("yyyyMMdd").format(new Date()) + String.format("%02d", r.nextInt(9999));
    }

    protected static long timeGen() {
        return System.currentTimeMillis();
    }

    protected static long tilNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }

    public static String getTargetId() {
        char[] temp = new char[5];
        for (int i = 0; i < 5; i++) {
            temp[i] = A2Z[r.nextInt(26)];
        }
        String string = new String(temp);
        Integer max = 999999;
        Integer min = 10000;
        int s = r.nextInt(max) % (max - min + 1) + min;
        return string + s;

    }

    public static String getTranSid() {
        Lock lock = new ReentrantLock();
        lock.lock();
        String temp = null;
        AtomicInteger atomicInteger = new AtomicInteger();
        try {
            String currDate = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
            Integer max = 999;
            Integer min = 100;
            int s = r.nextInt(max) % (max - min + 1) + min;
            temp = currDate + s;

        } finally {
            lock.unlock();
        }
        return temp;
    }

    public static String getTranSid19() {
        Lock lock = new ReentrantLock();
        lock.lock();
        String temp = null;
        AtomicInteger atomicInteger = new AtomicInteger();
        try {
            String currDate = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
            Integer max = 99;
            Integer min = 10;
            int s = r.nextInt(max) % (max - min + 1) + min;
            temp = currDate + s;
        } finally {
            lock.unlock();
        }
        return temp;
    }

    public static String getIcbcTimeStamp() {
        DateFormat dateFormatStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Lock lock = new ReentrantLock();
        lock.lock();
        String temp = null;
        AtomicInteger atomicInteger = new AtomicInteger();
        try {
            String currDate = dateFormatStamp.format(new Date());
            Integer max = 999999;
            Integer min = 100000;
            int s = r.nextInt(max) % (max - min + 1) + min;
            temp = currDate + "." + s;
        } finally {
            lock.unlock();
        }
        return temp;
    }

    public static String getIcbcReqSid() {
        DateFormat formatSid = new SimpleDateFormat("yyyyMMddHHmmss");
        Lock lock = new ReentrantLock();
        lock.lock();
        String temp = null;
        AtomicInteger atomicInteger = new AtomicInteger();
        try {
            String currDate = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
            Integer max = 9999;
            Integer min = 1000;
            int s = r.nextInt(max) % (max - min + 1) + min;
            temp = currDate + "." + s;
        } finally {
            lock.unlock();
        }
        return temp;
    }

    public static String getChannelNo() {
        return "1004" + getTranSid();
    }

    public static String getSuppayChannelNo() {
        return "1005" + getTranSid();
    }

    public static String getSeriaNo(){
        return System.currentTimeMillis() + RandomUtil.randomNStr(5);

    }


    public static void main(String[] args) {
        System.out.println(getIcbcReqSid());
        System.out.println(getIcbcTimeStamp());
        System.out.println(getIcbcTimeStamp());
        System.out.println(getTargetId());
        System.out.println(getTranSid());
    }
}
